home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 1.iso
/
ARGONET
/
PD
/
FILER
/
TARSRC.SPK
/
c
/
tar
< prev
next >
Wrap
Text File
|
1994-09-13
|
9KB
|
381 lines
/* Tape Archive Programme */
#include <signal.h>
#include "tar.h"
#include "args.h"
#include "options.h"
#include "perms.h"
#include "dir.h"
#include "rmt.h"
#include "tapeio.h"
#include "replace.h"
#include "table.h"
#include "extract.h"
static char *version = "[1.2b] (" __DATE__ ")";
int CreateArchive;
int ArchiveFileSpecified;
int IgnoreArchiveErrors;
int DoNotExtractFileDates;
int UseListFile;
int ConvertExclamationMark;
int AppendToArchive;
int SwapExtensionToDir;
int ListArchivesContents;
int Verbose;
int ConfirmActions;
int ExtractFromArchive;
int CompressFiles;
int Reblock;
int PeriodSlashConversion;
int FormatFloppies;
int MultipleVolumes;
int GNUmultipleVolumes;
int NoDiskDestroyConfirmation;
int QuietExecution;
int SwapInWholePath;
int CommaFileTypes;
int UnixArchive;
int VeryVerbose;
int AddFileTypeExtension;
int ConvertCompressExtension;
int UseCanonicalisedPaths;
int MaxLeafLength = ADFS_MAXLEAFLENGTH;
int tarFileType;
int MaxExtLength = 3;
tapedevice_t tapedevice;
int driveno;
char format = 'E';
char *listfile = "!tarlist";
char *ArchiveName;
int ArchiveOpen;
FILE *ArchiveFD;
int rmt_fd;
int UserInterrupt;
Block_t *TmpBlock;
Block_t Block;
int NumBlocksRead;
int nblock=20;
int recno;
int first;
int DiscNo=1;
int compression;
int isArchie;
#if WITH_PWD
int InitialUnset;
char InitialPreviousDir[MAXPATHLEN];
char InitialCurrentDir[MAXPATHLEN];
#endif
char ScrapName[MAXPATHLEN];
char ScrapNameZ[MAXPATHLEN];
char CompressTemplate[MAXPATHLEN];
char DecompressTemplate[MAXPATHLEN];
char CompressExt[256];
static int ArchiveIsStdIO;
static int GotInitialDirectories = 0;
void Terminate(int n) {
if (GotInitialDirectories) {
#if WITH_PWD
if (InitialUnset) {
os_cli("nodir");
} else {
ChangeCurrentDir(InitialPreviousDir);
ChangeCurrentDir(InitialCurrentDir);
}
#endif
}
switch (tapedevice) {
case tapedevice_FILE:
if (ArchiveOpen) {
fclose(ArchiveFD);
if (AppendToArchive && !ArchiveIsStdIO) {
SetFileType(ArchiveName, tarFileType);
}
}
break;
case tapedevice_RMT:
if (ArchiveOpen) {
rmtclose(rmt_fd);
}
break;
}
exit(n);
} /* Terminate */
char Decision(char default_answer) {
char c;
c = getchar();
if (c != '\n')
while (getchar() != '\n')
;
else
c = default_answer;
return (c);
} /* Decision */
int chkos(os_error *Error) {
char answer;
if (Error != NULL) {
fprintf(stderr, "tar: OS error: %s\n", Error->errmess);
if (!QuietExecution) {
fprintf(stderr, "tar: continue? ");
answer = Decision('y');
}
if (QuietExecution || answer == 'n' || answer == 'N') {
Terminate(15);
}
return(0);
}
return(1);
} /* chkos */
int ExecuteCommand(char *Template, char *Arg1, char *Arg2, int Warn) {
char *sp, *dp;
char OSCommand[256];
dp = OSCommand;
while (*Template) {
if (*(Template) != '%')
*(dp++) = *(Template++);
else {
Template++;
sp = NULL;
if (*Template == '1')
sp = Arg1;
else if (*Template == '2')
sp = Arg2;
if (sp == NULL)
*(dp++) = *(Template - 1);
else {
while (*sp)
*(dp++) = *(sp++);
Template++;
}
}
}
*dp = '\0';
if (system(OSCommand) != 0) {
if (Warn)
fprintf(stderr,"Warning: \"%s\" failed.\n",OSCommand);
return 0;
}
return 1;
} /* ExecuteCommand */
void InterruptHandler(int dummy) {
signal(SIGINT, SIG_IGN);
UserInterrupt++;
} /* InterruptHandler */
void AbortHandler(int dummy) {
signal(SIGABRT, SIG_IGN);
UserInterrupt++;
} /* AbortHandler */
void TerminateHandler(int dummy) {
signal(SIGTERM, SIG_IGN);
UserInterrupt++;
} /* TerminateHandler */
void compress_cleanup(void) {
remove(ScrapName);
remove(ScrapNameZ);
} /* compress_cleanup */
void PrintBlocks(FILE *fd, long blocks) {
fprintf(fd,"%ld block",blocks);
if (blocks != 1)
fputc('s',fd);
} /* PrintBlocks */
void usage(void) {
fprintf(stderr,"tar: usage: tar [-]cmd[opt] ARCHIVE [LIST] [BLKS] [-C DIR] file1 file2 ...\n");
fputs("\
Commands: c create a new archive\n\
r append files to end of archive\n\
t list the contents of an archive\n\
x extract files from an archive\n\
",stderr);
fputs("\
Options: b BLKS blocking factor BLKS (block size = BLKS x 512 bytes)\n\
e LENGTH maximum length of extension to use in UNIX file names\n\
f ARCHIVE read/write archive from file ARCHIVE (mandatory)\n\
i ignore checksum errors and zero blocks (normally EOF)\n\
l [LIST] read list of files from file LIST or !tarlist as default\n\
m do not extract date and times of files\n\
p convert '!' in RISC OS names to '_' in UNIX names\n\
s swap extension in filename (see documentation)\n\
v verbosely list what files we process\n\
w ask for confirmation\n\
z compress files before archiving\n\
B re-block as we read\n\
C DIR change to directory DIR\n\
E '.' in UNIX names will be converted to '/'\n\
F format disc in drive 0 (multiple volumes & E-format only)\n\
G use GNU tar multiple volume archiving\n\
M use multiple volume archiving\n\
O do not ask for confimation to format or write raw discs\n\
L LEN maximum file/directory name is LEN when extracting (default 10)\n\
P use RISC OS 3 path canonicalise instead of own routine\n\
Q quit immediately if error occurs, do not prompt for action\n\
S swap extensions in whole path\n\
T file types appended to names as with RISC-OS NFS\n\
U UNIX archive mode (no Archimedes extensions)\n\
V very verbose: also display files that are not extracted\n\
X add RISC OS file type as extension to file name in archive\n\
Z convert UNIX '.Z' to '/Z' when extracting\n\
Please read the documentation file for further information. I will take no\n\
responsibility for damage or loss of data due to the use of this programme.\n",
stderr);
fprintf(stderr,
"RISC OS tar %s by Frank Lancaster, Copyright (C) 1991-1994.\n", version);
fprintf(stderr,
"This programme is public domain. You may not charge anything for it.\n");
Terminate(16);
} /* usage */
void ChkScrapName(void) {
char *cp;
if (ScrapName[0] != '\0')
return;
if ((cp = getenv(SCRAP_VAR)) == NULL) {
fprintf(stderr,"tar: system variable %s not set\n",SCRAP_VAR);
Terminate(17);
}
strcpy(ScrapName,cp);
strcpy(ScrapNameZ,ScrapName);
strcat(ScrapNameZ,CompressExt);
compress_cleanup();
} /* GetScrapName */
int main(int argc, char *argv[]) {
char *cp;
if (argc < 2) {
usage();
}
argv[argc] = 0;
argv++;
for (cp = *argv++; *cp; cp++)
argv += CheckOption(&cp,*argv);
#if WITH_PWD
if ((InitialUnset = CurrentDirUnset()) == 0) {
ChangeCurrentDir("\\");
(void)GetCurrentDir(InitialPreviousDir);
ChangeCurrentDir("\\");
(void)GetCurrentDir(InitialCurrentDir);
}
#endif
GotInitialDirectories = 1;
if ((cp = getenv(TAR_FILETYPE_VAR)) != NULL)
tarFileType = (int)strtoul(cp,NULL,16);
else
tarFileType = 0xC46;
if ((cp = getenv(COMPEXT_VAR)) != NULL)
strcpy(CompressExt,cp);
else
strcpy(CompressExt,"/Z");
if ((cp = getenv(COMPRESS_VAR)) != NULL)
strcpy(CompressTemplate,cp);
else
strcpy(CompressTemplate,"compress < %1 > %2");
if ((cp = getenv(DECOMPRESS_VAR)) != NULL)
strcpy(DecompressTemplate,cp);
else
strcpy(DecompressTemplate,"compress -d < %1 > %2");
InitArgs(argv);
if (!AppendToArchive && !ExtractFromArchive && !ListArchivesContents ||
AppendToArchive && ExtractFromArchive ||
ListArchivesContents && ExtractFromArchive ||
AppendToArchive && ListArchivesContents) {
usage();
}
if (CompressFiles) {
ChkScrapName();
}
if (ArchiveName == NULL && tapedevice != tapedevice_DISC) {
fprintf(stderr,"tar: no archive file specified; use 'f' option\n");
Terminate(18);
}
TmpBlock = (union HeaderBlock *)malloc(nblock*RECORDSIZE);
if (TmpBlock == NULL) {
fprintf(stderr, "tar: blocksize %d too big, can't get memory\n",nblock);
Terminate(19);
}
if (AppendToArchive) {
if (GetArg(0) == NULL) {
fprintf(stderr,"tar: error: no files specified\n");
Terminate(20);
}
signal(SIGINT, InterruptHandler);
signal(SIGABRT, AbortHandler);
signal(SIGTERM, TerminateHandler);
if (strcmp(ArchiveName, "-") == 0) {
if (CreateArchive == 0) {
fprintf(stderr,"tar: cannot append to standard output archives\n");
Terminate(21);
}
ArchiveIsStdIO = 1;
ArchiveFD = stdout;
nblock = 1;
} else {
open_writetape();
}
ReplaceFiles();
Terminate(UserInterrupt ? 22 : 0);
}
if (strcmp(ArchiveName, "-") == 0) {
ArchiveIsStdIO = 1;
ArchiveFD = stdin;
nblock = 1;
} else {
open_readtape();
}
if (ExtractFromArchive) {
ExtractFiles();
} else {
ListContents();
}
Terminate(UserInterrupt ? 23 : 0);
} /* main */